﻿using NCS.IConnect.Core.Utilities;
using NCS.IConnect.Core.WebApi.Authorization;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Web.Http.Controllers;
using System.Web.Http.Description;

namespace NCS.IConnect.Core.WebApi.Description
{
    /// <summary>
    /// The HTTP action specific descriptor.
    /// </summary>
    public class ApiActionDescriptor
    {
        /// <summary>
        /// Gets the controller descriptor.
        /// </summary>
        /// <value>The controller descriptor.</value>
        [JsonIgnore]
        public ApiControllerDescriptor ControllerDescriptor { get; private set; }

        /// <summary>
        /// Gets the <see cref="HttpActionDescriptor"/>
        /// </summary>
        /// <value>The <see cref="HttpActionDescriptor"/></value>
        [JsonIgnore]
        public HttpActionDescriptor HttpActionDescriptor { get; private set; }

        /// <summary>
        /// Gets the documentation provider.
        /// </summary>
        /// <value>The documentation provider.</value>
        [JsonIgnore]
        public IDocumentationProvider DocumentationProvider { get; private set; }

        /// <summary>
        /// Gets the name of the action.
        /// </summary>
        /// <value>The name of the action.</value>
        public string ActionName { get; private set; }

        /// <summary>
        /// Gets the description.
        /// </summary>
        /// <value>The description.</value>
        public string Description { get; private set; }

        /// <summary>
        /// Gets the <see cref="RequestDescriptor"/>.
        /// </summary>
        /// <value>The <see cref="RequestDescriptor"/>.</value>
        public RequestDescriptor Request { get; private set; }

        /// <summary>
        /// Gets the <see cref="ResponseDescriptor"/>s.
        /// </summary>
        /// <value>The <see cref="ResponseDescriptor"/>s.</value>
        public ResponseDescriptor[] Responses { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="ApiActionDescriptor"/> class.
        /// </summary>
        /// <param name="controllerDescriptor">The controller descriptor.</param>
        /// <param name="httpActionDescriptor">The HTTP action descriptor.</param>
        public ApiActionDescriptor(ApiControllerDescriptor controllerDescriptor, HttpActionDescriptor httpActionDescriptor)
        {
            Guard.ArgumentNotNull(controllerDescriptor, "controllerDescriptor");
            Guard.ArgumentNotNull(httpActionDescriptor, "httpActionDescriptor");

            this.ControllerDescriptor = controllerDescriptor;
            this.HttpActionDescriptor = httpActionDescriptor;
            this.DocumentationProvider = controllerDescriptor.DocumentationProvider;
            this.Description = controllerDescriptor.DocumentationProvider.GetDocumentation(httpActionDescriptor);
            this.ActionName = httpActionDescriptor.ActionName;

            List<ResponseDescriptor> responseDescriptors = new List<ResponseDescriptor>();
            this.Request = new RequestDescriptor(this);
            foreach (ResponseAttribute responseAttribute in httpActionDescriptor.GetCustomAttributes<ResponseAttribute>())
            {
                responseDescriptors.Add(new ResponseDescriptor(this, responseAttribute));
            }
            if (httpActionDescriptor.ControllerDescriptor.GetCustomAttributes<BuiltInApiAttribute>().Any())
            {
                ResponseAttribute responseAttribute = new ResponseAttribute(HttpStatusCode.Unauthorized, ResponseScenarios.Common.Unauthorized, "E0008");
                responseDescriptors.Add(new ResponseDescriptor(this, responseAttribute));
            }
            this.Responses = responseDescriptors.ToArray();
        }
    }
}